home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 March
/
EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso
/
earcd
/
patches
/
xpkdopus.lha
/
xpkdopus5
/
xpkdopus.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-10-21
|
6KB
|
271 lines
/*
xpk file (un)packer - special version for DirectoryOpus5 usage
Copyright © 1995 by Daniel Balster
*/
#include <exec/exec.h>
#include <dos/dos.h>
#include <libraries/xpk.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <stdio.h>
#include <string.h>
#include <rexx/storage.h>
#include <rexx/rxslib.h>
struct Library *XpkBase;
#define DEBUG 1
#ifdef DEBUG
void kprintf(UBYTE *fmt,...);
#define bug kprintf
#define D(X) X
#else
#define D(X)
#endif
#define AllocStruct(X) AllocVec(sizeof(struct X),MEMF_CLEAR|MEMF_PUBLIC)
#define FreeStruct(X) FreeVec(X)
#define ifnot(expr) if(!(expr))
typedef enum { false=0, true=~(false) } bool;
extern struct ExecBase *SysBase;
LONG __regargs PackFile(struct DosLibrary *DOSBase,struct Library *XpkBase,
char *,struct FileInfoBlock *,char *,char *,LONG,char *,LONG,LONG);
LONG __regargs UnPackFile(struct DosLibrary *DOSBase,struct Library *XpkBase,
char *,char *,struct FileInfoBlock *,char *);
LONG __asm __saveds ChunkFunc(register __a1 struct XpkProgress *);
/**************************/
STRPTR lister;
char dopus[32];
char buffer[256];
LONG __asm __saveds ChunkFunc(register __a1 struct XpkProgress *P)
{
char result[2];
sprintf(buffer,
"sys:rexxc/rx \"address %s;options results;"
"lister set %s progress name '%s (%ld%% gain)';"
"lister set %s progress count %ld;"
"lister query %s abort;call export('%08lx'x,RESULT);\"",
dopus,lister,P->Activity,P->CF,lister,P->Done,lister,result);
if (!Execute (buffer,0,0)) return SIGBREAKF_CTRL_C;
if (result[0]=='1') return SIGBREAKF_CTRL_C;
return (LONG) SetSignal(0L,SIGBREAKF_CTRL_C)&SIGBREAKF_CTRL_C;
}
struct Hook ChunkHook = {{0L},ChunkFunc};
/**************************/
#define TAGIT(i,t,d) xtags[i].ti_Tag=t; xtags[i].ti_Data=(ULONG)d;
#define ENDIT(i) xtags[i].ti_Tag=TAG_DONE;
struct TagItem xtags[10];
struct XpkFib xfib;
char buf[108];
char xpkerr[XPKERRMSGSIZE];
void __regargs tmpname()
{
UWORD Index;
ULONG Addr;
for (Index=0, Addr=(ULONG)FindTask(NULL); Index<8; Index++, Addr>>=4) buf[Index] = 'A'+(char)(Addr&15);
(void)strcpy(&buf[8],"..db");
}
#define ERR_PROTECTED (1)
#define ERR_MINSIZE (2)
#define ERR_XPK (3)
#define ERR_UNPACKED (4)
#define ERR_PACKED (5)
#define ERR_NOGAIN (6)
#define ERR_NODELETE (7)
#define ERR_NOTRENAMED (8)
#define ERR_EXAMINE (9)
#define ERR_OPENFILE (10)
#define ERR_MEMORY (11)
#define ERR_ARGS (12)
#define ERR_CURRENTDIR (13)
STRPTR errors[] =
{
0,
"Source is DELETE protected (D-bit)",
"File skipped because it is too small",
0,
"File is already packed",
"File is already unpacked",
"Could not reach any gain",
"Could not delete source file",
"Could not rename destination as source",
"Could not examine source file",
"Could not open source file",
"Internal memory allocation failed",
"Could not parse the arguments",
"Could not lock the source directory"
};
LONG xpack(struct FileInfoBlock *fib,BPTR file,STRPTR lib,STRPTR passwd,LONG minsize)
{
ULONG size;
if (fib->fib_Protection&FIBF_DELETE) return ERR_PROTECTED;
if (fib->fib_Size<=minsize) return ERR_MINSIZE;
TAGIT(0,XPK_GetError,xpkerr);
TAGIT(1,XPK_InFH,file);
ENDIT(2);
if (XpkExamine(&xfib,xtags)) return ERR_XPK;
if (xfib.Type!=XPKTYPE_UNPACKED) return ERR_UNPACKED;
tmpname();
TAGIT(0,XPK_Password,passwd);
TAGIT(1,XPK_GetError,xpkerr);
TAGIT(2,XPK_FindMethod,lib);
TAGIT(3,XPK_ChunkHook,&ChunkHook);
TAGIT(4,XPK_FileName,fib->fib_FileName);
TAGIT(5,XPK_InFH,file);
TAGIT(6,XPK_OutName,buf);
TAGIT(7,XPK_GetOutLen,&size);
ENDIT(8);
if (XpkPack(xtags)) return ERR_XPK;
if (size>fib->fib_Size) { DeleteFile(buf);return ERR_NOGAIN; }
return 0l;
}
LONG xunpack(struct FileInfoBlock *fib,BPTR file,STRPTR passwd)
{
if (fib->fib_Protection&FIBF_DELETE) return ERR_PROTECTED;
TAGIT(0,XPK_GetError,xpkerr);
TAGIT(1,XPK_InFH,file);
ENDIT(2);
if (XpkExamine(&xfib,xtags)) return ERR_XPK;
if (xfib.Type!=XPKTYPE_PACKED) return ERR_PACKED;
tmpname();
TAGIT(0,XPK_Password,passwd);
TAGIT(1,XPK_GetError,xpkerr);
TAGIT(2,XPK_ChunkHook,&ChunkHook);
TAGIT(3,XPK_FileName,fib->fib_FileName);
TAGIT(4,XPK_InFH,file);
TAGIT(5,XPK_OutName,buf);
ENDIT(6);
if (XpkUnpack(xtags)) return ERR_XPK;
return 0;
}
#define TMPLATE "DIR/A/K,FILE/A/K,LIB=METHOD/K,PASSWD/K,PACK/S,MINSIZE/N/K,LISTER/A/K,REXXPORT/A/K"
struct {
STRPTR dirname;
STRPTR filename;
STRPTR libname;
STRPTR passwd;
ULONG pack;
ULONG* minsize;
STRPTR handle;
STRPTR dopus;
} args = {0};
LONG main()
{
struct RDArgs *rda;
struct FileInfoBlock *fib;
BPTR file;
LONG err=100;
if (!(XpkBase=OpenLibrary(XPKNAME,2l))) return 20;
if(rda = ReadArgs(TMPLATE,(LONG*)&args,0))
{
BPTR olddir,dir;
if (dir = Lock(args.dirname,ACCESS_READ))
{
olddir = CurrentDir(dir);
if (fib = AllocVec(sizeof(*fib),MEMF_CLEAR|MEMF_PUBLIC))
{
if (file = Open(args.filename,MODE_OLDFILE))
{
if (ExamineFH(file,fib))
{
ULONG mz;
if (args.minsize) mz = *args.minsize;
else mz = fib->fib_Size-1;
lister = args.handle;
strcpy(dopus,args.dopus);
if (args.pack)
err = xpack(fib,file,args.libname,args.passwd,mz);
else
err = xunpack(fib,file,args.passwd);
}
else err = ERR_EXAMINE;
Close(file);
if (err==0)
{
if (fib->fib_Comment[0]) SetComment(buf,fib->fib_Comment);
if (fib->fib_Protection) SetProtection(buf,fib->fib_Protection);
SetFileDate(buf,&fib->fib_Date);
if (!DeleteFile(fib->fib_FileName)) err = ERR_NODELETE;
if (!Rename(buf,fib->fib_FileName)) err = ERR_NOTRENAMED;
}
}
else err = ERR_OPENFILE;
FreeVec(fib);
}
else err = ERR_MEMORY;
CurrentDir(olddir);
UnLock(dir);
}
else err = ERR_CURRENTDIR;
FreeArgs(rda);
}
else err = ERR_ARGS;
if (err)
{
char ebuf[128];
if (err==ERR_XPK)
sprintf(ebuf,"rx \"address %s;dopus request '''%s''' 'Ok'\"",dopus,xpkerr);
else
sprintf(ebuf,"rx \"address %s;dopus request '''Error: %s''' 'Ok'\"",dopus,errors[err]);
Execute(ebuf,0,0);
}
return 0;
}